library sysutil;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  StrUtils,
  JNI,
  Classes,
  dialogs,
  windows,
  ZipMstr;

{$R *.res}
procedure ExtractZip(ADLLPath : string; AFileName : string; ADir : string);
begin
  if (ADir = '') and (LowerCase(RightStr(AFileName,4)) = '.zip') then
    ADir := ExtractFilePath(AFileName);

  if not DirectoryExists(ADir) then
    CreateDir(ADir);

  with TZipMaster.Create(nil) do
  begin
    ZipFileName := AFileName;
    ExtrBaseDir := ADir;
    ExtrOptions := [];
    DLLDirectory := ADLLPath;
    
    ExtrOptions := ExtrOptions + [ExtrDirNames];
    ExtrOptions := ExtrOptions + [ExtrOverwrite];

    Extract;

    Free;
  end;

end;

procedure RunProcess(AFileName: string);
var
  PI:TProcessInformation;
  SI:TStartUpInfo;
begin
  FillChar(SI,sizeof(SI),#0);
  with SI do begin
    cb:=sizeof(SI);
    dwFlags:=StartF_UsesTDHandles or STARTF_USESHOWWINDOW;
    lptitle:=nil;
    wShowWindow:=SW_Show;
  end;
  CreateProcess(PChar(AFileName),nil,nil,nil,true,DETACHED_PROCESS,nil,nil,SI,PI);

end;

procedure Java_com_bluesky_system_NativeRunner_execApp(PEnv: PJNIEnv;obj:jobject; AZipFileName : JString; appName:JString);stdcall;
var
  JVM:TJNIEnv;

  lZipFileName,
  lDllPathName,
  lDllPath,
  lNativeAppZipFilePathName,
  lNativeAppExecFilePathName,
  lNativeAppExecFileName:string;
begin
  JVM:=TJNIEnv.Create(PEnv);
  lZipFileName :=JVM.UnicodeJStringToString(AZipFileName);
  lNativeAppExecFileName :=JVM.UnicodeJStringToString(appName);

  lDllPathName := GetModuleName(HInstance);
  lDllPath := ExtractFilePath(lDllPathName);

  if Trim(lZipFileName) <> '' then
  begin
    lNativeAppZipFilePathName := lDllPath + lZipFileName;
    if FileExists(lNativeAppZipFilePathName) then
      ExtractZip(lDllPath,lNativeAppZipFilePathName,lDllPath)
    else
      ShowMessage('zip file ['+lNativeAppZipFilePathName +'] not exist.');
  end;

  //then exec the .exe file
  lNativeAppExecFilePathName := lDllPath + lNativeAppExecFileName;

  if FileExists(lNativeAppExecFilePathName) then
    RunProcess(lNativeAppExecFilePathName)
  else
    ShowMessage('target application ['+lNativeAppExecFilePathName +'] not exist.');

  JVM.Free;
end;

exports
  Java_com_bluesky_system_NativeRunner_execApp;

begin

end.
